/**
 * 服务
 * */
package org.zmhhxl.sample3.oauth2.a.authentications.model;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonTypeName;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.util.Assert;

import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.*;

//@JsonDeserialize(using = CustomOAuth2UserDeserializer.class)
//@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "@class")
//@JsonSubTypes({
//        @JsonSubTypes.Type(value = CustomOAuth2User.class, name = "CustomOAuth2User")
//})
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "@class")
@JsonTypeName("CustomOAuth2User")
@Slf4j
@Data
@JsonSerialize
@NoArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public class CustomOAuth2User implements OAuth2User, Serializable {
    //private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID;
    private static final long serialVersionUID = 1L;
    //private static final long serialVersionUID = -6963523161322981431L;
    //private  OAuth2User delegate;
    /**
     * 自增id
     */
    private Integer id;
    /**
     * 三方登录唯一id userName
     */
    private String uniqueId;
    /**
     * 三方登录用户名
     */
    private String thirdUsername;
    /**
     * 三方登录获取的认证信息
     */
    private String credentials;
    /**
     * 三方登录获取的认证信息的过期时间
     */
    private LocalDateTime credentialsExpiresAt;

    /**
     * 三方登录类型
     */
    private String type;
    /**
     * 主域
     */
    private String domain;
    /**
     * 协议
     * */
    private String protocol;
    /**
     * 网格地址
     */
    private String location;
    /**
     * 用户表主键
     */
    private Long userId;

    /**
     * 绑定时间
     */
    private LocalDateTime createTime;
    /**
     * 修改时间
     */
    private LocalDateTime updateTime;

    /**
     * 用户名、昵称 nickname
     */
    private String name;
    /**
     * 邮箱
     */
    private String email;
    /**
     * 手机号
     */
    private String mobile;
    /**
     * 头像地址
     */
    private String avatarUrl;
    /**
     * 用户来源
     */
    private String sourceFrom;
    /**
     * 三方账号字段名
     */
    private String nameAttributeKey;
    /**
     * 三方用户属性信息
     */
    private  Map<String, Object> attributes;
    /**
     * 三方用户权限信息(scope)
     */
    private  Collection<? extends GrantedAuthority> authorities;

    // 默认构造器
//    public CustomOAuth2User() {
//        this.delegate = null;
//        this.authorities = null;
//    }

    // 使用@JsonCreator标注的工厂方法
    //@JsonCreator
    // @Safe                                     /*@JsonProperty("authorities")*/
    public CustomOAuth2User(OAuth2User delegate, String nameAttributeKey) {
        Assert.notEmpty(delegate.getAttributes(), "attributes cannot be empty");
        if (delegate == null) {
            throw new IllegalArgumentException("zmhhxl Delegate cannot be null");
        }
//        if (nameAttributeKey == null) {
//            throw new IllegalArgumentException("attributes name cannot be null");
//        }
        Assert.notEmpty(delegate.getAttributes(), "attributes cannot be empty");
        this.authorities = (delegate.getAttributes() != null)
                ? Collections.unmodifiableSet(new LinkedHashSet<>(this.sortAuthorities(delegate.getAuthorities())))
                : Collections.unmodifiableSet(new LinkedHashSet<>(AuthorityUtils.NO_AUTHORITIES));
        this.attributes = Collections.unmodifiableMap(new LinkedHashMap<>(delegate.getAttributes()));
        this.nameAttributeKey = nameAttributeKey;
        //this.delegate = delegate;
        //this.authorities = authorities;
    }

//    @Override
//    public Map<String, Object> getAttributes() {
//        return supper.getAttributes();
//    }

    @Override
    public String getName() {
        return attributes.get(nameAttributeKey) + "";
    }

    @Override
    public String toString() {
        //return super.toString();
        StringBuilder sb = new StringBuilder();
        sb.append("Name: [");
        sb.append(this.getName());
        sb.append("], Granted Authorities: [");
        sb.append(getAuthorities());
        sb.append("], User Attributes: [");
        sb.append(getAttributes());
        sb.append("]");
        return sb.toString();
    }

    /**
     * 将权限排序
     *
     * @param authorities 权限
     * @return 排序后的权限信息
     */
    private Set<GrantedAuthority> sortAuthorities(Collection<? extends GrantedAuthority> authorities) {
        SortedSet<GrantedAuthority> sortedAuthorities = new TreeSet<>(
              Comparator.comparing(GrantedAuthority::getAuthority));
        sortedAuthorities.addAll(authorities);
        return sortedAuthorities;
    }

}


//    public class CustomOAuth2UserDeserializer extends StdDeserializer<CustomOAuth2User> {
//        public CustomOAuth2UserDeserializer() {
//            this(null);
//        }
//
//        protected CustomOAuth2UserDeserializer(Class<?> vc) {
//            super(vc);
//        }
//
//        @Override
//        public CustomOAuth2User deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
//            ObjectMapper mapper = new ObjectMapper();
//            Map<String, Object> map = mapper.readValue(p.getValueAsString(), Map.class);
//
//            // 根据 map 创建 CustomOAuth2User 实例
//            return new CustomOAuth2User(map);
//        }
//    }


//    @Override
//    public Collection<? extends GrantedAuthority> getAuthorities() {
//        return this.authorities;
//    }

//    @Override
//    public int hashCode() {
//        //return super.hashCode();
//        int result = Objects.hash(this.getName(), this.getAuthorities(), this.getAttributes(), this.nameAttributeKey);
//
//        //this.getName().hashCode();
////        result = 31 * result + this.getAuthorities().hashCode();
////        result = 31 * result + this.getAttributes().hashCode();
////        result = 31 * result + this.delegate.hashCode();
//        return result;
//    }

//    @Override
//    public boolean equals(Object obj) {
//        if (this == obj) {
//            return true;
//        }
//        if (obj == null || this.getClass() != obj.getClass()) {
//            return false;
//        }
//        CustomOAuth2User that = (CustomOAuth2User) obj;
//        if (!this.getName().equals(that.getName())) {
//            return false;
//        }
//        if (!this.getAuthorities().equals(that.getAuthorities())) {
//            return false;
//        }
//        if (!Objects.equals(this.delegate, that.delegate)) {
//            return false;
//        }
//        return this.getAttributes().equals(that.getAttributes());
//        //return super.equals(obj);
//    }
